home *** CD-ROM | disk | FTP | other *** search
/ Space & Astronomy / Space and Astronomy (October 1993).iso / mac / VIEWERS / X11 / XLOADIMG.TAR / rotate.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  4KB  |  145 lines

  1. /* rotate.c
  2.  *
  3.  * rotate an image
  4.  *
  5.  * Contributed by Tom Tatlow (tatlow@dash.enet.dec.com)
  6.  */
  7.  
  8. #include "copyright.h"
  9. #include "image.h"
  10.  
  11. /* rotate_bitmap()
  12.  * converts an old bitmap bit position into a new one
  13.  */
  14. void rotate_bitmap(num, pos, width, height, new_num, new_pos)
  15. int      num;                /* Source byte number       */
  16. int      pos;                /* Source bit position      */
  17. int    width;                /* Width of source bitmap   */
  18. int   height;                /* Height of source bitmap  */
  19. int *new_num;                /* Destination byte number  */
  20. int *new_pos;                /* Destination bit position */
  21. {
  22.   int   slen;                /* Length of source line      */
  23.   int   dlen;                /* Length of destination line */
  24.   int sx, sy;
  25.   int dx, dy;
  26.  
  27.   slen = (width / 8) + (width % 8 ? 1 : 0);
  28.   dlen = (height / 8) + (height % 8 ? 1 : 0);
  29.   sy = num / slen;
  30.   sx = ((num - (sy * slen)) * 8) + pos;
  31.   dx = (height - sy) - 1;
  32.   dy = sx;
  33.   *new_num = (dx / 8) + (dy * dlen);
  34.   *new_pos = dx % 8;
  35. }
  36.  
  37. /* rotate()
  38.  * rotates an image
  39.  */
  40. Image *rotate(simage, rotate, verbose)
  41. Image *simage;                /* Image to rotate             */
  42. int    rotate;                /* Number of degrees to rotate */
  43.   char buf[BUFSIZ];            /* New title                   */
  44.   Image    *image1;            /* Source image                */
  45.   Image    *image2;            /* Destination image           */
  46.   byte         *sp;            /* Pointer to source data      */
  47.   byte         *dp;            /* Pointer to destination data */
  48.   int     slinelen;            /* Length of source line       */
  49.   int     dlinelen;            /* Length of destination line  */
  50.   int       bit[8];            /* Array of hex values         */
  51.   int         x, y;
  52.   int         i, b;
  53.   int   newx, newy;
  54.   int   newi, newb;
  55.   byte      **yptr;
  56.  
  57.   bit[0] = 128;
  58.   bit[1] =  64;
  59.   bit[2] =  32;
  60.   bit[3] =  16;
  61.   bit[4] =   8;
  62.   bit[5] =   4;
  63.   bit[6] =   2;
  64.   bit[7] =   1;
  65.  
  66.   goodImage(simage, "rotate");
  67.  
  68.   if (verbose)
  69.     { printf("  Rotating image by %d degrees...", rotate);
  70.       fflush(stdout);
  71.     }
  72.   sprintf(buf, "%s (rotated by %d degrees)", simage->title, rotate);
  73.  
  74.   image1 = simage;
  75.   do {
  76.     rotate -= 90;
  77.     switch (image1->type) {
  78.     case IBITMAP:
  79.       image2= newBitImage(image1->height, image1->width);
  80.       for (x= 0; x < image1->rgb.used; x++) {
  81.     *(image2->rgb.red + x)= *(image1->rgb.red + x);
  82.     *(image2->rgb.green + x)= *(image1->rgb.green + x);
  83.     *(image2->rgb.blue + x)= *(image1->rgb.blue + x);
  84.       }
  85.       slinelen= (image1->width / 8) + (image1->width % 8 ? 1 : 0);
  86.       sp = image1->data;
  87.       dp = image2->data;
  88.       for (i = 0; i < (slinelen * image1->height); i++)
  89.     for (b = 0; b < 8; b++)
  90.       if (sp[i] & bit[b])
  91.         { rotate_bitmap(i, b, image1->width, image1->height, &newi, &newb);
  92.           dp[newi] |= bit[newb];
  93.         }
  94.       break;
  95.       
  96.     case IRGB:
  97.       image2= newRGBImage(image1->height, image1->width, image1->depth);
  98.       for (x= 0; x < image1->rgb.used; x++) {
  99.     *(image2->rgb.red + x)= *(image1->rgb.red + x);
  100.     *(image2->rgb.green + x)= *(image1->rgb.green + x);
  101.     *(image2->rgb.blue + x)= *(image1->rgb.blue + x);
  102.       }
  103.       image2->rgb.used= image1->rgb.used;
  104.       /* FALLTHRU */
  105.  
  106.     case ITRUE:
  107.       if (TRUEP(image1))
  108.     image2= newTrueImage(image1->height, image1->width);
  109.  
  110.       /* build array of y axis ptrs into destination image
  111.        */
  112.  
  113.       yptr= (byte **)lmalloc(image1->width * sizeof(char *));
  114.       dlinelen= image1->height * image1->pixlen;
  115.       for (y= 0; y < image1->width; y++)
  116.     yptr[y]= image2->data + (y * dlinelen);
  117.  
  118.       /* rotate
  119.        */
  120.  
  121.       sp= image1->data;
  122.       for (y = 0; y < image1->height; y++)
  123.     for (x = 0; x < image1->width; x++) {
  124.       valToMem(memToVal(sp, image1->pixlen),
  125.            yptr[x] + ((image1->height - y - 1) * image1->pixlen),
  126.            image1->pixlen);
  127.       sp += image1->pixlen;
  128.     }
  129.       lfree(yptr);
  130.       break;
  131.     default:
  132.       printf("rotate: Unsupported image type\n");
  133.       exit(1);
  134.     }
  135.     freeImage(image1);
  136.     image1 = image2;
  137.   } while (rotate);
  138.   image1->title= dupString(buf);
  139.   if (verbose)
  140.     printf("done\n");
  141.   return(image1);
  142. }
  143.  
  144.